package com.qhyiyun.baseweb.util;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.pqc.legacy.math.linearalgebra.ByteUtils;
import org.bouncycastle.util.encoders.Hex;

import javax.crypto.Cipher;
import java.nio.charset.StandardCharsets;
import java.security.*;

import java.security.spec.ECGenParameterSpec;
import java.util.Base64;

public class Sm2Util {
    private static int signLength;

    static {
        Security.addProvider(new BouncyCastleProvider());
    }

    public static void main(String[] args) throws Exception {
        KeyPairGenerator generator = KeyPairGenerator.getInstance("EC", "BC");
        generator.initialize(new ECGenParameterSpec("sm2p256v1"));
        KeyPair keyPair = generator.generateKeyPair();
        PublicKey publicKey = keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();
        System.out.println("puk------"+ Base64.getEncoder().encodeToString(publicKey.getEncoded()));
        // 模拟加密数据
        String originalMessage = "Hello, SM2!";
        byte[] encryptedData = encrypt(originalMessage.getBytes(StandardCharsets.UTF_8), publicKey, privateKey);
        byte[] decryptedData = decrypt(encryptedData, privateKey, publicKey);

        System.out.println("Original Message: " + originalMessage);
        System.out.println("Encrypted Data: " + Hex.toHexString(encryptedData));
        System.out.println("Decrypted Message: " + new String(decryptedData, StandardCharsets.UTF_8));
    }

    public static byte[] encrypt(byte[] plaintext, PublicKey publicKey, PrivateKey privateKey) throws Exception {
        Signature signer = Signature.getInstance("SM3withSM2", "BC");
        signer.initSign(privateKey);
        signer.update(plaintext);
        byte[] signature = signer.sign();
        signLength=signature.length;
        System.out.println(signature.length);
        // 这里假设直接拼接了密文和签名，实际应用中可能需要更复杂的结构处理
        byte[] combinedData = new byte[plaintext.length + signature.length];
        System.arraycopy(plaintext, 0, combinedData, 0, plaintext.length);
        System.arraycopy(signature, 0, combinedData, plaintext.length, signature.length);

        Cipher cipher = Cipher.getInstance("SM2", "BC");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        return cipher.doFinal(combinedData);
    }

    public static byte[] decrypt(byte[] ciphertext, PrivateKey privateKey, PublicKey publicKey) throws Exception {
        Cipher cipher = Cipher.getInstance("SM2", "BC");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] decryptedCombined = cipher.doFinal(ciphertext);

        // 分离数据和签名的逻辑需根据实际加密时的结构来实现
        int signatureLength = signLength; // SM3签名长度通常为64字节，根据实际情况调整
        byte[] decryptedData = new byte[decryptedCombined.length - signatureLength];
        System.arraycopy(decryptedCombined, 0, decryptedData, 0, decryptedData.length);

        // 这里省略了签名验证过程，实际应用中需要验证解密后数据的前部分与签名是否匹配
        // 使用Signature类的verify方法进行验证

        return decryptedData;
    }
}
